import React from 'react';
import PropTypes from 'prop-types';
import cn from 'classnames';

import Icon from '../../../../components/Icon';
import s from './Tree.module.css';

export default function Tree({ className, data, selectedPath, onClick }) {
	const treeRows = React.useMemo(
		() =>
			treeRowsBuilder({
				selectedPath,
				data,
				onClick,
			}),
		[data, selectedPath]
	);

	return <div className={cn(className, s.tree)}>{treeRows}</div>;
}

Tree.propTypes = {
	className: PropTypes.string,
	selectedPath: PropTypes.string.isRequired,
	onClick: PropTypes.func.isRequired,
	data: PropTypes.shape({
		name: PropTypes.string.isRequired,
		children: PropTypes.object,
	}),
};

Tree.defaultProps = {
	className: s.tree,
};

function treeRowsBuilder({ data, selectedPath, onClick }) {
	const rows = [
		<div
			key={data.id}
			className={cn(s.row, s.clickable, {[s.selected]: selectedPath === data.id})}

		>
			<span className={s.content}>
				<Icon
					className={cn(s.iconBtn, s.iconCollapse, {
						[s.collapse]: !data.isChildrenExpand,
					})}
					onClick={() => {
						onClick(data)
					}}
					type="tree-toggle"
				/>
				<span onClick={() => onClick(data, 'showDetail')} className='df aic pl8 pr8'>
					<Icon className={s.iconBtn} type="tree-root" />
					<span className={s.pathName}>{data.value}</span>
					{data.isAbnormal && (
						<Icon type="tree-abnormal" className={s.moduleIcon} />
					)}
				</span>
			</span>
		</div>,
	];

	const queue = Object.values(data.children || {}).map(node => ({
		node,
		isExpand: data.isChildrenExpand,
	}));
	while (queue.length) {
		const { node, isExpand } = queue.shift();

		if (isExpand && node.isChildrenExpand && node.children) {
			queue.unshift(
				...Object.values(node.children).map(n => ({
					isExpand: node.isChildrenExpand,
					node: n,
				}))
			);
		}

		rows.push(
			<div
				key={node.id}
				className={cn(s.row, {
					[s.collapse]: !isExpand,
					[s.selected]: selectedPath === node.id,
					[s.hidden]: node.hidden,
				})}
			>
				<span
					className={s.content}
					style={{
						marginLeft: node.children
							? `${node.level}rem`
							: `calc(${node.level}rem + 1em)`,
					}}
				>
					{node.children && (
						<>
							<Icon
								className={cn(s.iconBtn, s.iconCollapse, {
									[s.collapse]: !node.isChildrenExpand,
								})}
								onClick={e => {
									onClick(node)
								}}
								type="tree-toggle"
							/>
						</>
					)}
					<span onClick={() => onClick(node, 'showDetail')} className='df aic pl8 pr8'>
						<Icon className={cn(s.iconBtn)} type={node.children ? "tree-folder" : 'tree-leaf'} />
						<span className={cn(s.pathName, { [s.matched]: node.isMatchFilter })}>
							{node.name === '\x01*\x02' ? '*' : node.name}
						</span>
						{node.change && <Icon type="tree-change" className={s.moduleIcon} />}
						{node.isAbnormal && (
							<Icon type="tree-abnormal" className={s.moduleIcon} />
						)}
					</span>
				</span>
			</div>
		);
	}

	return rows;
}
